using System.Collections;
using System.Collections.Generic;
using UnityEngine;

class TimerNode
{
    public TimerMgr.TimerHandler callback;
    public float duration; // 定时器触发的时间间隔;
    public float delay; // 第一次触发要隔多少时间;
    public int repeat; // 你要触发的次数;
    public float passedTime; // 这个Timer过去的时间;
    public object param; // 用户要传的参数
    public bool isRemoved; // 是否已经删除了
    public int timerId; // 标识这个timer的唯一Id号;
}

public class TimerMgr : UnitySingleton<TimerMgr>
{
    public delegate void TimerHandler(object param);

    private int autoIncId = 1;

    private Dictionary<int, TimerNode> timers = null;
    private List<TimerNode> removeTimers = null;
    private List<TimerNode> newAddTimers = null;

    // 初始化的入口
    public void Init()
    {
        this.timers = new Dictionary<int, TimerNode>();
        this.autoIncId = 1;

        this.removeTimers = new List<TimerNode>();
        this.newAddTimers = new List<TimerNode>();
    }

    private void Update()
    {
        float dt = Time.deltaTime;

        // 把新加进来的放入到我们的表里面来
        for (int i = 0; i < this.newAddTimers.Count; i++) {
            this.timers.Add(this.newAddTimers[i].timerId, this.newAddTimers[i]);
        }
        this.newAddTimers.Clear();
        // end

        foreach (TimerNode timer in this.timers.Values) {
            if (timer.isRemoved) {
                this.removeTimers.Add(timer);
                continue;
            }

            timer.passedTime += dt;
            if (timer.passedTime >= (timer.delay + timer.duration)) {
                // 做一次触发
                timer.callback(timer.param);
                timer.repeat--;
                timer.passedTime -= (timer.delay + timer.duration);
                timer.delay = 0; // 很重要;

                if (timer.repeat == 0)
                { // 触发次数结束，我们是不是要删除这个Timer; 
                    timer.isRemoved = true;
                    this.removeTimers.Add(timer);
                }
                // end 
            }
        }

        // 结束以后，清理掉要删除的Timer;
        for (int i = 0; i < this.removeTimers.Count; i++) {
            this.timers.Remove(this.removeTimers[i].timerId);
        }
        this.removeTimers.Clear();
        // end
    }
	
    public int ScheduleOnce(TimerHandler func, float delay)
    {
        return this.Schedule(func, 1, 0, delay);
    }

    public int ScheduleOnce(TimerHandler func, object param, float delay)
    {
        return this.Schedule(func, param, 1, delay);
    }

    // [repeat < 0 or repeat == 0 表示的是无限触发]
    public int Schedule(TimerHandler func, int repeat, float duration, float delay = 0.0f)
    {
        return Schedule(func, null, repeat, duration, delay);
    }

    // [repeat < 0 or repeat == 0 表示的是无限触发]
    public int Schedule(TimerHandler func, object param, int repeat, float duration, float delay = 0.0f)
    {
        TimerNode timer = new TimerNode();
        timer.callback = func;
        timer.param = param;
        timer.repeat = repeat;
        timer.duration = duration;
        timer.delay = delay;
        timer.passedTime = timer.duration;
        timer.isRemoved = false;

        timer.timerId = this.autoIncId;
        this.autoIncId++;

        // this.timers.Add(timer.timerId, timer);
        this.newAddTimers.Add(timer);
        return timer.timerId;
    }


    public void Unschedule(int timerId)
    {
        if (!this.timers.ContainsKey(timerId)) {
            return;
        }

        TimerNode timer = this.timers[timerId];
        timer.isRemoved = true;
    }
}
